

/**
 * 树模板是树状控件的基类, 菜单、树控件都是树状控件
 *
 * @class 树模板类
 * @param {zxt.data.TreeModel} sModel 树状数据模型
 * @param {String} sLabel 标签
 * @param {String} sText 描述
 */
zxt.ui.TreeTemplate= function( sModel, sLabel, sText ) {
  this._model = sModel;
  this._label = sLabel;
  this._text = sText;
  this._depth = null;
};

zxt.defineClazz(zxt.ui.TreeTemplate, zxt.ui.Widget);

/**
 * <p>该方法有两个功能，如果参数未定义，则返回当前的层级数设置；否则，设置层级数</p> 
 * @function
 * @param {int} v 层级数
 * @return {int} 如果参数未定义，则返回当前的层级数设置
 */
zxt.ui.TreeTemplate.prototype.depth = function(v){
  if (v === undefined) {	return this._depth;	}
  this._depth = v;
};

/**
 * <p>根据标签获取指定树节点</p>
 *
 * @function
 * @param {string} lb 树节点标签
 * @returns {zxt.ui.TTNode} 树节点对象
 */
zxt.ui.TreeTemplate.prototype.getNode = function(lb){
  var l = new Array();  
  var tlb = lb;
  l.push(tlb);
  do{
    var p = this._model.getParent(tlb);
	if ( p != null ) {
	  tlb = p.label;
  	  l.push(p.label);
	}
  }while( p != null )

  var nd = l.pop();
  var node = this._rootNode;
  while( nd != undefined ){
    node = node.getChildNode( nd );
    nd = l.pop();   
  }  
  return node;
};

/**
 * @private
 */
zxt.ui.TreeTemplate.prototype.renderSelf = function(){   
   
};


/**
 * <p>树模板节点</p>
 * @class
 * @param {zxt.ui.TreeTemplate} sTree 树模板节点所属树模板
 * @param {zxt.ui.TTNode} sParent 父节点
 * @param {string} sLabel 节点标签
 * @param {string} sText 节点标题
 * @param {boolean} sLeaf 是否是节点点
 * @param {object} sData 节点相关数据
 */
zxt.ui.TTNode = function( sTree, sParent, sLabel, sText, sLeaf, sData ) {
  this._tree = sTree;
  this._parent = sParent;

  this._label = sLabel; // if _label is null, this node is a virtual root node
  this._text = sText;
  this._leaf = sLeaf;
  this._data = sData;

  this._opened = false;
  this._childNodes  = [];
  this._status = -1; // -1: not loaded, 0: loading, 1: loaded    
};

zxt.defineClazz(zxt.ui.TTNode, zxt.ui.Widget);

/**
 * <p>该方法有两个功能，如果参数未定义，则返回当前的标签设置；否则，设置标签</p> 
 * @function
 * @param {String} v 标签设置
 * @return {String} 如果参数未定义，则返回当前的标签设置
 */
zxt.ui.TTNode.prototype.label = function(v){
  if (v === undefined) {	return this._label;	}
  this._label = v;
};

/**
 * <p>该方法有两个功能，如果参数未定义，则返回当前的节点标题；否则，设置节点标题</p>
 * 
 * @function
 * @param {String} v 节点标题
 * @return {String} 如果参数未定义，则返回当前的节点标题
 */
zxt.ui.TTNode.prototype.text = function(v){
  if (v === undefined) {	return this._text;	}
  this._text = v;
};

/**
 * <p>该方法有两个功能，如果参数未定义，则返回当前的叶子节点标识；否则，设置叶子节点标识</p>
 * @function
 * @param {boolean} v 叶子节点标识 true:是
 * @return {boolean} 如果参数未定义，则返回当前的叶子节点标识
 */
zxt.ui.TTNode.prototype.leaf = function(v){
  if (v === undefined) {	return this._leaf;	}
  this._leaf = v;
};

/**
 *  <p>该方法有两个功能，如果参数未定义，则返回当前的节点数据；否则，设置叶子节点数据</p>
 * 
 * @function
 * @param {Object} v 节点数据
 * @return {Object} 如果参数未定义，则返回当前的节点数据
 */
zxt.ui.TTNode.prototype.data = function(v){
  if (v === undefined) {	return this._data;	}
  this._data = v;
};

/**
 * <p>该方法有两个功能，如果参数未定义，则返回当前的节点打开/关闭状态；否则，设置节点的打开/关闭状态</p> 
 *
 * @function
 * @param {boolean} v true - 打开节点, false - 关闭节点o
 * @return {boolean} 如果参数未定义，则返回当前的节点打开/关闭状态
 */
zxt.ui.TTNode.prototype.open = function(v){
  if (v === undefined) {	return this._opened;	}
  this._opened = v;
};

/**
 * 
 * <p> 节点状态: -1: 未加载, 0: 加载中, 1: 已加载</p> 
 *
 * @function
 * @return {int} 节点状态 -1: 未加载, 0: 加载中, 1: 已加载
 */
zxt.ui.TTNode.prototype.status = function(){
  return this._status;  
};

/**
 * <p>父节点</p> 
 * 
 * @function
 * @return {zxt.ui.TTNode} 父节点
 */
zxt.ui.TTNode.prototype.parent = function(){
  return this._parent;
};

/**
 * <p>所属树模板</p> 
 *  
 * @function
 * @return {zxt.ui.TreeTemplate}  所属树模板
 */
zxt.ui.TTNode.prototype.tree = function(){
  return this._tree;
};

/**
 * <p>是否是顶级节点</p>
 * 
 * @function
 * @returns {boolean} 是否是顶级节点
 */
zxt.ui.TTNode.prototype.top = function(){
  return ( this._parent == null );
};

/**
 * <p>是否是虚根节点</p>
 * 
 * @function
 * @returns {boolean} 是否是虚根节点
 */
zxt.ui.TTNode.prototype.virtual = function(){
  return ( this._label == null );
};

/**
 * <p>获取节点的深度</p>
 * 
 * @function
 * @returns {int} 节点的深度
 */
zxt.ui.TTNode.prototype.depth = function(){
	var depth = 0;
	var treeItem = this;
	while( !treeItem.top() ){
		depth++;
		treeItem = treeItem._parent;
	}
	return depth;
};

/**
 * <p>增加子节点</p>
 * 
 * @function
 * @param {zxt.ui.TTNode} sNode 子节点
 */
zxt.ui.TTNode.prototype.addChild = function( sNode ){
  this._childNodes.push(sNode);
};

/**
 * <p>获取子节点</p>
 * 
 * @function
 * @returns {zxt.ui.TTNode[]} sNode 所有子节点
 */
zxt.ui.TTNode.prototype.getChildNodes = function(){
  var td = this._tree.depth();
  if ( td!=null && td < this.depth()+1 ) {  
    return new Array();
  }
  this.load();
  return this._childNodes;
};

/**
 * <p>根据标签获取子节点</p>
 * 
 * @function
 * @param {string} lb 子节点标签
 * @returns {zxt.ui.TTNode[]} sNode 指定标签的子节点
 */
zxt.ui.TTNode.prototype.getChildNode = function(lb){
   var children = this.getChildNodes();
   for (  var i = 0; i < children.length; i++ ) {
     var child = children[i];
	 if ( child.label() === lb ) {
       return child;
	 }
   }
   return null;
};

/**
 * @private
 */
zxt.ui.TTNode.prototype.load = function(force){
  if ( force || this._status === -1 ) {
    this._status = 0;
	this._childNodes = new Array();
    var children = new Array();
    if ( this._label === null ) {
      children = this.tree()._model.getTopNodes();
    } else {
      children = this.tree()._model.getChildren(this._label);
    }

    for( var i=0; i<children.length; i++ ){
	  var sub = this._createChildNode(children[i]); 
	  this._childNodes.push(sub);
    }
    this._status = 1;
  } 
};

/**
 * 
 * @private
 */
zxt.ui.TTNode.prototype._createChildNode = function(child){
  alert("_createChildNode NOT implemented");
};

/**
 * 打开节点
 * @function
 */
zxt.ui.TTNode.prototype.expand = function() {  
  this._opened = true;
  this.load();
  this.render();
};

/**
 * <p>收缩节点</p> 
 * @function
 */
zxt.ui.TTNode.prototype.collapse = function(){
  this._opened = false;   
  this.render();
};

/**
 * @private
 */
zxt.ui.TTNode.prototype.renderSelf = function(){
   alert("render NOT implemented");
};

